//
//  AppManager.swift
//  QFTZ
//
//  Created by apple on 2020/3/31.
//  Copyright © 2020 iOSCoderZhao. All rights reserved.
//

import Foundation
import UIKit
import StoreKit

// MARK: - 校验字符的表达式
public enum RegexCharacterType: String {
    /// 汉字
    case type1 = "^[\\u4e00-\\u9fa5]{0,}$"
    /// 英文和数字 ^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
    case type2 = "^[A-Za-z0-9]{4,40}$"
    /// 长度为3-20的所有字符
    case type3 = "^.{3,20}$"
    /// 由26个英文字母组成的字符串
    case type4 = "^[A-Za-z]+$"
    /// 由26个大写英文字母组成的字符串
    case type5 = "^[A-Z]+$"
    /// 由26个小写英文字母组成的字符串
    case type6 = "^[a-z]+$"
    /// 由数字和26个英文字母组成的字符串
    case type7 = "^[A-Za-z0-9]+$"
    /// 由数字、26个英文字母或者下划线组成的字符串 ^\w+$ 或 ^\w{3,20}$
    case type8 = "^\\w+$"
    /// 中文、英文、数字包括下划线
    case type9 = "^[\\u4E00-\\u9FA5A-Za-z0-9_]+$"
    /// 中文、英文、数字但不包括下划线等符号 ^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
    case type10 = "^[\\u4E00-\\u9FA5A-Za-z0-9]+$"
    /// 可以输入含有^%&',;=?$\"等字符
    case type11 = "[^%&',;=?$\\x22]+"
    /// 禁止输入含有~的字符
    case type12 = "[^~\\x22]+"
}

// MARK: - 校验数字的表达式
public enum RegexDigitalType: String {
    /// 数字
    case type1 = "^[0-9]*$"
    /// 零和非零开头的数字
    case type2 = "^(0|[1-9][0-9]*)$"
    /// 非零开头的最多带两位小数的数字
    case type3 = "^([1-9][0-9]*)+(\\.[0-9]{1,2})?$"
    /// 非零的正整数：^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
    case type4 = "^[1-9]\\d*$"
    /// 非零的负整数：^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
    case type5 = "^-[1-9]\\d*$"
    /// 非负整数：^\d+$ 或 ^[1-9]\d*|0$
    case type6 = "^\\d+$"
    /// 非正整数：^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
    case type7 = "^((-\\d+)|(0+))$"
    /// 非负浮点数：^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
    case type8 = "^\\d+(\\.\\d+)?$"
    /// 非正浮点数：^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
    case type9 = "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$"
    /// 正浮点数：^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
    case type10 = "^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"
    /// 负浮点数：^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
    case type11 = "^-([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*)$"
    /// 浮点数：^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
    case type12 = "^(-?\\d+)(\\.\\d+)?$"
    /// 手机号
    case type13 = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199)\\d{8}$"
}

// MARK: - 常用正则表达式
//验证手机号（20位以内的数值）
public func isPhoneNumber(number: String) -> Bool {
    let tel = "^1[3-9]\\d{9}$"
    let phone = NSPredicate.init(format: "SELF MATCHES %@", tel)
    return phone.evaluate(with: number)
}

//6位验证码
public func isCode(code: String) -> Bool {
    let verificationCode = NSPredicate.init(format: "SELF MATCHES %@", "^\\d{6}$")
    return verificationCode.evaluate(with: code)
}

//验证密码 (6-16位字母数字组成的密码)
public func is_passWord(word: String) -> Bool {
    let verificationWord = NSPredicate.init(format: "SELF MATCHES %@", "^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z\\d]{6,16}$")
    return verificationWord.evaluate(with: word)
}

//验证汉字
public func isHanzi(name: String) -> Bool {
    let verificationName = NSPredicate.init(format: "SELF MATCHES %@", "^[\u{4e00}-\u{9fa5}]{1,}$")
    return verificationName.evaluate(with: name)
}

//验证数字
public func isNumb(name: String) -> Bool {
    let verificationName = NSPredicate.init(format: "SELF MATCHES %@", "^[0-9]{1,}$")
    return verificationName.evaluate(with: name)
}

//验证昵称 （12位内的汉字，字母，数字）
public func isName(name: String) -> Bool {
    let verificationName = NSPredicate.init(format: "SELF MATCHES %@", "^[\u{4e00}-\u{9fa5}0-9A-Za-z]{1,12}$")
    return verificationName.evaluate(with: name)
}

//验证邮箱
public func isEmail(email: String) -> Bool {
    let verificationName = NSPredicate.init(format: "SELF MATCHES %@", "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$")
    return verificationName.evaluate(with: email)
}

// 宽、高适配规则(取整，防止除不尽，导致约束警告)
public func adapt_size(_ size: CGFloat) -> CGFloat {
    if UIDevice.isiPad { let newSize = Int(size * 1.4); return CGFloat(newSize) }
    let newSize = Int(UIDevice.ratio * size)
    return CGFloat(newSize)
}

/// 根据后台返回图片大小，调整UIImageView大小
/// - Parameters:
///   - size: 图片大小
public func changeImageViewSize(size: CGSize) -> CGSize {
    var imageW: CGFloat = size.width
    var imageH: CGFloat = size.height
    let scale: CGFloat = imageW / imageH
    let minW: CGFloat = (UIDevice.width - 2 * adapt_size(16) - adapt_size(20)) / 3.0
    let maxW: CGFloat = UIDevice.width - adapt_size(150)
    let maxH: CGFloat = UIDevice.height - UIDevice.navigtionHeight - UIDevice.tabBarHeight - adapt_size(200)

    // 过宽处理
    if imageW > maxW {
        imageW = maxW
        imageH = imageW / scale
    }

    // 过窄处理
    if imageW <= minW {
        imageW = minW
        imageH = imageW / scale
    }

    // 过高处理
    if imageH > maxH {
        imageH = maxH
        imageW = imageH * scale
    }

    return CGSize(width: imageW, height: imageH)
}

/// 时间戳(毫秒)转换时分秒字符串
/// - Parameter timeInterval: 时间戳(秒)
public func convertTimeIntervalToString(timeInterval: Int64) -> String? {
    // 转化成秒
    let newTimeInterval = timeInterval / 1000
    
    if newTimeInterval < 60 { // 秒
        return String(format: "00:%02lu", newTimeInterval)
    } else if newTimeInterval >= 60 && newTimeInterval < 3600 { // 分、秒
        return String(format: "%02lu:%02lu", newTimeInterval/60, newTimeInterval%60)
    } else if newTimeInterval >= 3600 { // 时、分、秒
        return String(format: "%02lu:%02lu:%02lu", newTimeInterval/3600, newTimeInterval%3600/60, newTimeInterval%60)
    }
    return nil
}

/// 将 >= 10000 的整数转化为 以 ' 万' 为单位, 保留一位小数的字符串, 第二位小数向上进一位, < 10000 的不变
/// 如:  12300 --> 1.3,    12800 --> 1.3
public func transformIntToString(_ number: Int) -> String {
    guard number >= 10000 else {
        return "\(number)"
    }
    let num = Float(number) / 1000.0
    let upNum = ceilf(num) / 10.0
    return String(format: "%.1f万", upNum)
}

public func fatoryBase64ToJson(base64:String) -> String{
    
    let decodedData:NSData? = NSData(base64Encoded:base64, options: .ignoreUnknownCharacters)
    
    let decodedString = NSString(data: decodedData! as Data, encoding: String.Encoding.utf8.rawValue)!
    
    return decodedString as String
}

public func factoryJsonToBase64(jsonStr:String) -> String {
    let originData: NSData = jsonStr.data(using: String.Encoding.utf8)! as NSData
    let encodeResult: String = originData.base64EncodedString(options: .endLineWithLineFeed)
    return encodeResult
}

// MARK: - 常用功能区
/// 浏览器打开网址
public func openURL(url: URL) {

    guard UIApplication.shared.canOpenURL(url) else {
        return
    }

    guard #available(iOS 10.0, *) else {
        UIApplication.shared.openURL(url)
    }

    UIApplication.shared.open(url)
}

/// 跳转系统设置界面
public func openSettingsURL() {

    guard let url = URL(string: UIApplicationOpenSettingsURLString) else {
        return
    }

    openURL(url: url)
}

//拨打电话
public func callPhone(number: String) {
    guard !number.isEmpty, let url = URL(string: "telprompt://(\(number)") else {
        return
    }

    openURL(url: url)
}

/// 应用内弹出更新
public func updateApp(vc: UIViewController, appId: String) {
    guard !appId.isEmpty else { return }
    let controller = SKStoreProductViewController()
    controller.loadProduct(withParameters: [SKStoreProductParameterITunesItemIdentifier: appId]) { result, error in
        if !result{
            controller.dismiss(animated: true)
        }
    }

    vc.showDetailViewController(controller, sender: vc)
}

/// 前往App Store
/// - Parameter appid: App的 ID，在app创建的时候生成的
public func evaluationInAppStore(appid: String) {

    let urlString = "https://itunes.apple.com/cn/app/id" + appid + "?mt=8" //12

    guard let url = URL(string: urlString) else {
        return
    }

    openURL(url: url)
}

/// 获取本机IP
public func getIPAddress() -> String? {
    var addresses = [String]()
    var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil
    if getifaddrs(&ifaddr) == 0 {
        var ptr = ifaddr
        while (ptr != nil) {
            let flags = Int32(ptr!.pointee.ifa_flags)
            var addr = ptr!.pointee.ifa_addr.pointee
            if (flags & (IFF_UP | IFF_RUNNING | IFF_LOOPBACK)) == (IFF_UP | IFF_RUNNING) {
                if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0) {
                        if let address = String(validatingUTF8:hostname) {
                            addresses.append(address)
                        }
                    }
                }
            }
            ptr = ptr!.pointee.ifa_next
        }
        freeifaddrs(ifaddr)
    }
    return addresses.first
}
